home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 7
/
PC World Interactive 7.iso
/
program
/
cprog.EXE
/
ICONBMP.ZIP
/
ICO2BMP.C
next >
Wrap
C/C++ Source or Header
|
1996-01-08
|
8KB
|
309 lines
/*--------------------------------------------------------------------------*/
/* */
/* Ico2bmp - Small utility program, which reads a icon file (.ico), extracts*/
/* the color part of the icon, and generates a bitmap file (.bmp). */
/* */
/* Author: Niels Erik Holm, ICL DATA A/S, Copenhagen Denmark, neh@rci.dk */
/* No copyrights apply, no Warranty */
/* */
/*--------------------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <dos.h>
char * Version = "Ico2bmp v1.0 - Extracts color bitmap from icon file - Author: neh@rci.dk";
typedef struct {
WORD icoReserved; /* Reserved, must be set to 0 */
WORD icoResourceType; /* Resource type, 1 for icon resources */
WORD icoResourceCount; /* Number of images in the file */
} IconFileHeader;
typedef struct {
BYTE Width; /* Width in pixels */
BYTE Height; /* Height in pixels */
BYTE ColorCount; /* Number of colors */
BYTE Reserved1;
WORD Reserved2;
WORD Reserved3;
DWORD icoDIBSize; /* Size in bytes of the pixel array */
DWORD icoDIBOffset; /* Offset in bytes from beginning of file */
/* to pixel array. */
} IconRscDir;
typedef struct {
IconFileHeader IHead; /* Icon file header */
IconRscDir IDir; /* Icon resource directory */
BYTE IBits[1000];
} IconFile;
BITMAPFILEHEADER bmFH;
BITMAPINFOHEADER bmIH;
RGBQUAD bmCol[16];
unsigned char Idata[1000];
unsigned char Odata[1000];
int opterr = 1;
int optind = 1;
int optopt;
char * optarg;
struct find_t fb;
int MoreFiles;
static int getopt(int,char **,char *);
static int ProcessFile(char *,char *);
static void ManipulateBits(BYTE *,BYTE *,int);
static void usage(void);
main(argc,argv)
int argc;
char *argv[];
{
int opt,attr;
char * Fptr;
char InFileSpec[64];
char FirstName[64];
char InName[64];
char OutName[64];
InFileSpec[0] = 0;
attr = 0;
while ((opt = getopt(argc,argv,"hi:")) != -1)
switch (opt) {
case 'h':
usage();
exit(1);
break;
case 'i':
strcpy(InFileSpec,optarg);
break;
}
if (InFileSpec[0] == 0) {
usage();
exit(1);
}
if ((Fptr = strchr(InFileSpec,'.')) == NULL)
strcat(InFileSpec,".ico");
MoreFiles = (_dos_findfirst(InFileSpec,attr,&fb) == 0);
if (!MoreFiles) {
fprintf (stderr,"No files matching %s\n",InFileSpec);
exit(1);
}
strcpy(FirstName,fb.name);
while (MoreFiles) {
strcpy(InName,fb.name);
strcpy(OutName,InName);
Fptr = strchr(OutName,'.');
strcpy(Fptr,".bmp");
(void) ProcessFile(InName,OutName);
MoreFiles = ((_dos_findnext(&fb)==0) && (strcmp(FirstName,fb.name)!=0));
}
}
static int ProcessFile(char * InFileName,char * OutFileName)
{
FILE * Ifile;
FILE * Ofile;
IconRscDir* pIRD;
BITMAPINFOHEADER * pBMIH;
RGBQUAD * pRGB;
BYTE * pColorData;
BYTE * pMonoData;
int i,j,Ino,Cno,DataNo,ColorTabSize,BitMapSize,Pixels,BitsPerPixel;
char * Iptr;
unsigned char * Bptr;
if ((Ifile = fopen(InFileName,"rb")) == NULL) {
fprintf (stderr,"Error opening input file %s\n",InFileName);
return(0);
}
fread (Idata,1,sizeof(Idata),Ifile);
fclose(Ifile);
if ((Ofile = fopen(OutFileName,"wb")) == NULL) {
fprintf (stderr,"Error opening output file %s\n",OutFileName);
return(0);
}
fprintf (stdout,"Processing %s -> %s",InFileName,OutFileName);
Iptr = Idata;
if (((IconFileHeader *)Iptr)->icoReserved != 0) {
fprintf (stderr,"\nSorry! Invalid icon file.\n");
return(0);
}
Ino = ((IconFileHeader *)Iptr)->icoResourceCount;
if (Ino != 1) {
fprintf (stderr,"\nSorry! Ico2bmp can only handle icon file with one icons.\n");
return(0);
}
Iptr += sizeof(IconFileHeader);
pIRD = (IconRscDir *)Iptr;
pBMIH= (BITMAPINFOHEADER *)(Idata + pIRD->icoDIBOffset);
pRGB = (RGBQUAD *)((BYTE *)pBMIH+sizeof(BITMAPINFOHEADER));
ColorTabSize = pIRD->ColorCount*sizeof(RGBQUAD);
pColorData = (BYTE *)((BYTE *)pRGB+ColorTabSize);
BitsPerPixel = pBMIH->biBitCount;
Pixels = pIRD->Width*pIRD->Height*BitsPerPixel;
BitMapSize = Pixels/8;
pMonoData = (BYTE *)(pColorData + BitMapSize);
Cno=pBMIH->biBitCount;
if (Cno==1)
Cno=2;
else if (Cno==4)
Cno=16;
else if (Cno==8)
Cno=256;
else if (Cno==24)
Cno=0;
if (Cno != 16) {
fprintf (stderr,"\nSorry! Ico2bmp can only handle 16 color icons\n");
return(0);
}
bmFH.bfType = 'B' | 'M'<<8;
bmFH.bfSize = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize+BitMapSize;
bmFH.bfOffBits = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize;
bmIH.biSize = pBMIH->biSize;
bmIH.biWidth = pBMIH->biWidth;
bmIH.biHeight = pBMIH->biHeight/2;
bmIH.biPlanes = pBMIH->biPlanes;
bmIH.biBitCount = pBMIH->biBitCount;
bmIH.biCompression = pBMIH->biCompression;
bmIH.biSizeImage = BitMapSize;
bmIH.biXPelsPerMeter = pBMIH->biXPelsPerMeter;
bmIH.biYPelsPerMeter = pBMIH->biYPelsPerMeter;
bmIH.biClrUsed = pBMIH->biClrUsed;
bmIH.biClrImportant = Cno;
for (i=0;i<Cno;i++)
bmCol[i] = *((RGBQUAD*)((BYTE*)pRGB + i*sizeof(RGBQUAD)));
ManipulateBits(pColorData,pMonoData,Pixels);
memcpy(Odata,pColorData,BitMapSize);
fwrite(&bmFH,sizeof(bmFH),1,Ofile);
fwrite(&bmIH,sizeof(bmIH),1,Ofile);
fwrite(&bmCol[0],ColorTabSize,1,Ofile);
fwrite(&Odata[0],BitMapSize,1,Ofile);
fclose(Ofile);
fprintf (stdout,"\n");
return(1);
}
static void ManipulateBits(BYTE * pColorData,BYTE * pMonoData,int pixels)
/* Works only on 16 color bitmaps */
{
register int i,MonoBits,XorMask,j;
register BYTE * pMD;
pMD = pMonoData;
MonoBits = *pMD;
j=0;
for (i=0;i<pixels/2;i++) {
if (MonoBits & 0x80)
*(pColorData+i) |= 0xF0;
MonoBits <<= 1;
j++;
if (MonoBits & 0x80)
*(pColorData+i) |= 0x0F;
MonoBits <<= 1;
j++;
if (j==8) {
++pMD;
MonoBits = *pMD;
j=0;
}
}
}
static void usage()
{
fprintf (stdout,"%s\n",Version);
fprintf (stdout,"Usage: ico2bmp -i <inputfile> [-h]\n");
fprintf (stdout,"\n");
fprintf (stdout," -h: Display this help\n");
fprintf (stdout," -i: Name of input file. If no extension is specified .ico is used.\n");
fprintf (stdout," Wildcards are allowed. Ex. -i *.ico\n");
}
#define index strchr
#define ERR(s, c) if(opterr){\
extern int write();\
char errbuf[2];\
errbuf[0] = c; errbuf[1] = '\n';\
(void) fprintf(stderr, argv[0], (unsigned)strlen(argv[0]));\
(void) fprintf(stderr, s, (unsigned)strlen(s));\
(void) fprintf(stderr, errbuf, 2);}
static int getopt(int argc, char ** argv, char * opts)
{
static int sp = 1;
register int c;
register char *cp;
if(sp == 1)
if(optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return(-1);
else if(strcmp(argv[optind], "--") == 0) {
optind++;
return(-1);
}
optopt = c = argv[optind][sp];
if(c == ':' || (cp=index(opts, c)) == 0) {
ERR(": illegal option -- ", c);
if(argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return('?');
}
if(*++cp == ':') {
if(argv[optind][sp+1] != '\0')
optarg = &argv[optind++][sp+1];
else if(++optind >= argc) {
ERR(": option requires an argument -- ", c);
sp = 1;
return('?');
} else
optarg = argv[optind++];
sp = 1;
} else {
if(argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = 0;
}
return(c);
}